import requests
import math
from datetime import datetime
from .market_state_analyzer import MarketStateAnalyzer

class CryptoAnalyzer:
    def __init__(self):
        self.symbols = ['BTCUSDT']
        self.historical_data = {}
        self.strategy_signals = {}
        self.backtester = Backtester()
        self.market_state_analyzer = MarketStateAnalyzer()
        
        for symbol in self.symbols:
            self.historical_data[symbol] = {}
            self.strategy_signals[symbol] = {}
    
    def fetch_historical_data(self, symbol, interval, limit=500):
        try:           
            url = f"https://bnapi.bnlex.top/fapi/fapi/v1/klines?symbol={symbol}&interval={interval}&limit={limit}"
            response = requests.get(url)
            data = response.json()
            
            return [
                {
                    'time': math.floor(item[0] / 1000),
                    'open': float(item[1]),
                    'high': float(item[2]),
                    'low': float(item[3]),
                    'close': float(item[4]),
                    'volume': float(item[5]),
                    'closeTime': item[6]
                }
                for item in data
            ]
        except Exception as e:
            print(f"获取{symbol}历史数据失败: {e}")
            return None
    
    def convert_to_higher_timeframe(self, data, factor):
        converted = []
        for i in range(0, len(data) - factor + 1, factor):
            chunk = data[i:i+factor]
            new_candle = {
                'time': chunk[0]['time'],
                'open': chunk[0]['open'],
                'high': max(c['high'] for c in chunk),
                'low': min(c['low'] for c in chunk),
                'close': chunk[-1]['close'],
                'volume': sum(c['volume'] for c in chunk),
                'closeTime': chunk[-1]['closeTime']
            }
            converted.append(new_candle)
        return converted
    
    async def fetch_data_for_all_symbols(self, interval):
        for symbol in self.symbols:
            fetch_interval = interval
            if interval == '10m':
                fetch_interval = '5m'
            elif interval == '30m':
                fetch_interval = '15m'
            elif interval == '5m':
                fetch_interval = '5m'

            raw_data = self.fetch_historical_data(symbol, fetch_interval)
            if not raw_data:
                continue

            if interval in ['10m', '30m']:
                data = self.convert_to_higher_timeframe(raw_data, 2)
            else:
                data = raw_data

            self.historical_data[symbol][interval] = data
    
    def calculate_rsi(self, data, period=14):
        if len(data) < period + 1:
            return [None] * len(data)
        
        rsi = [None] * period
        avg_gain = 0.0
        avg_loss = 0.0
        
        for i in range(1, period + 1):
            change = data[i]['close'] - data[i-1]['close']
            if change > 0:
                avg_gain += change
            else:
                avg_loss += abs(change)
        
        avg_gain /= period
        avg_loss /= period
        
        rs = avg_gain / avg_loss if avg_loss != 0 else 100
        rsi.append(100 - (100 / (1 + rs)))
        
        for i in range(period + 1, len(data)):
            change = data[i]['close'] - data[i-1]['close']
            gain = change if change > 0 else 0
            loss = abs(change) if change < 0 else 0
            
            avg_gain = (avg_gain * (period - 1) + gain) / period
            avg_loss = (avg_loss * (period - 1) + loss) / period
            
            rs = avg_gain / avg_loss if avg_loss != 0 else 100
            rsi.append(100 - (100 / (1 + rs)))
        
        return rsi
    
    def calculate_ema(self, data, period):
        ema = [None] * (period - 1)
        if len(data) < period:
            return ema
        
        sum_close = sum(d['close'] for d in data[:period])
        ema.append(sum_close / period)
        
        multiplier = 2 / (period + 1)
        for i in range(period, len(data)):
            current_ema = (data[i]['close'] - ema[i-1]) * multiplier + ema[i-1]
            ema.append(current_ema)
        
        return ema
    
    def calculate_macd(self, data, short_period=12, long_period=26, signal_period=9):
        if len(data) < long_period + signal_period:
            return {
                'dif': [None] * len(data),
                'dea': [None] * len(data),
                'macd': [None] * len(data)
            }
        
        short_ema = self.calculate_ema(data, short_period)
        long_ema = self.calculate_ema(data, long_period)
        
        dif = []
        for s, l in zip(short_ema, long_ema):
            if s is not None and l is not None:
                dif.append(s - l)
            else:
                dif.append(None)
        
        dea_data = [{'close': d if d is not None else 0, 'time': data[i]['time']} 
                   for i, d in enumerate(dif)]
        dea = self.calculate_ema(dea_data, signal_period)
        
        macd = []
        for d, s in zip(dif, dea):
            if d is not None and s is not None:
                macd.append((d - s) * 2)
            else:
                macd.append(None)
        
        return {'dif': dif, 'dea': dea, 'macd': macd}
    
    def calculate_kdj(self, data, period=9, k_period=3, d_period=3):
        if len(data) < period + d_period:
            return {
                'k': [None] * len(data),
                'd': [None] * len(data),
                'j': [None] * len(data)
            }
        
        k_values = []
        d_values = []
        j_values = []
        
        for i in range(len(data)):
            if i < period - 1:
                k_values.append(None)
                d_values.append(None)
                j_values.append(None)
                continue
            
            high = max(data[j]['high'] for j in range(i - period + 1, i + 1))
            low = min(data[j]['low'] for j in range(i - period + 1, i + 1))
            close = data[i]['close']
            
            if high == low:
                rsv = 0
            else:
                rsv = (close - low) / (high - low) * 100
            
            if k_values[i-1] is not None:
                k = (k_values[i-1] * (k_period - 1) + rsv) / k_period
            else:
                k = rsv
            
            if d_values[i-1] is not None:
                d = (d_values[i-1] * (d_period - 1) + k) / d_period
            else:
                d = k
            
            j = 3 * k - 2 * d
            
            k_values.append(k)
            d_values.append(d)
            j_values.append(j)
        
        return {'k': k_values, 'd': d_values, 'j': j_values}
    
    def calculate_ma(self, data, period):
        ma = []
        for i in range(len(data)):
            if i < period - 1:
                ma.append(None)
                continue
            
            sum_close = sum(data[j]['close'] for j in range(i - period + 1, i + 1))
            ma.append(sum_close / period)
        
        return ma
    
    def get_trend(self, values, index):
        if index < 2 or values[index] is None or values[index-1] is None:
            return 'neutral'
        return 'up' if values[index] > values[index-1] else 'down'
    
    def get_macd_trend(self, macd, index):
        if index < 2 or macd['dif'][index] is None or macd['dea'][index] is None:
            return 'neutral'
        
        dif = macd['dif'][index]
        dea = macd['dea'][index]
        prev_dif = macd['dif'][index-1]
        prev_dea = macd['dea'][index-1]
        
        macd_above = dif > dea
        macd_prev_above = prev_dif > prev_dea
        macd_increasing = dif > prev_dif
        dea_increasing = dea > prev_dea
        
        if macd_above:
            if not macd_prev_above:
                return 'crossUp'
            return 'strongUp' if macd_increasing and dea_increasing else 'up'
        else:
            if macd_prev_above:
                return 'crossDown'
            return 'strongDown' if not macd_increasing and not dea_increasing else 'down'
    
    def get_kdj_cross(self, kdj, index):
        if index < 2 or kdj['k'][index] is None or kdj['d'][index] is None:
            return 'neutral'
        
        k = kdj['k'][index]
        d = kdj['d'][index]
        prev_k = kdj['k'][index-1]
        prev_d = kdj['d'][index-1]
        
        if k > d and prev_k < prev_d:
            return 'goldenCross'
        if k < d and prev_k > prev_d:
            return 'deathCross'
        if k > d:
            return 'above'
        if k < d:
            return 'below'
        return 'neutral'
    
    def calculate_fisher(self, data, period=9):
        if len(data) < period:
            return [None] * len(data)
    
        fisher = [None] * len(data)
        mid_prices = [(d['high'] + d['low']) / 2 for d in data]
    
        for i in range(period, len(data)):
            highest_high = max(mid_prices[i-period:i+1])
            lowest_low = min(mid_prices[i-period:i+1])
            if highest_high == lowest_low:
                norm_price = 0
            else:
                norm_price = 2 * ((mid_prices[i] - lowest_low) / (highest_high - lowest_low)) - 1
            
            norm_price = max(-0.999, min(0.999, norm_price))
    
            if abs(norm_price) >= 0.999:
                fisher[i] = 0.0
            else:
                fisher[i] = 0.5 * math.log((1 + norm_price) / (1 - norm_price))
    
        return fisher
    
    def calculate_td_sequence(self, data):
        """计算TD序列指标"""
        if len(data) < 9:
            return {'buy_setup': [None] * len(data), 'sell_setup': [None] * len(data), 
                   'buy_countdown': [None] * len(data), 'sell_countdown': [None] * len(data)}
        
        buy_setup = [None] * len(data)
        sell_setup = [None] * len(data)
        buy_countdown = [None] * len(data)
        sell_countdown = [None] * len(data)
        
        # TD买入设置：连续4根K线收盘价低于前一根K线收盘价的前2根K线收盘价
        for i in range(4, len(data)):
            # 买入设置条件
            if (data[i]['close'] < data[i-1]['close'] and 
                data[i-1]['close'] < data[i-2]['close'] and 
                data[i-2]['close'] < data[i-3]['close'] and 
                data[i-3]['close'] < data[i-4]['close']):
                
                # 检查是否满足TD买入设置的价格条件
                if (data[i]['close'] < min(data[i-2]['low'], data[i-3]['low']) or
                    data[i+1]['close'] < min(data[i-1]['low'], data[i-2]['low'])):
                    buy_setup[i] = 9
            
            # 卖出设置条件
            if (data[i]['close'] > data[i-1]['close'] and 
                data[i-1]['close'] > data[i-2]['close'] and 
                data[i-2]['close'] > data[i-3]['close'] and 
                data[i-3]['close'] > data[i-4]['close']):
                
                # 检查是否满足TD卖出设置的价格条件
                if (data[i]['close'] > max(data[i-2]['high'], data[i-3]['high']) or
                    data[i+1]['close'] > max(data[i-1]['high'], data[i-2]['high'])):
                    sell_setup[i] = 9
        
        # TD倒计时
        buy_count = 0
        sell_count = 0
        
        for i in range(9, len(data)):
            # 买入倒计时
            if buy_setup[i] == 9:
                buy_count = 1
                buy_countdown[i] = buy_count
            elif buy_count > 0 and buy_count < 13:
                if data[i]['close'] < data[i-1]['close']:
                    buy_count += 1
                    buy_countdown[i] = buy_count
                else:
                    buy_count = 0
            
            # 卖出倒计时
            if sell_setup[i] == 9:
                sell_count = 1
                sell_countdown[i] = sell_count
            elif sell_count > 0 and sell_count < 13:
                if data[i]['close'] > data[i-1]['close']:
                    sell_count += 1
                    sell_countdown[i] = sell_count
                else:
                    sell_count = 0
        
        return {
            'buy_setup': buy_setup,
            'sell_setup': sell_setup,
            'buy_countdown': buy_countdown,
            'sell_countdown': sell_countdown
        }
    
    def calculate_strategy_signals(self, data, strategy_name="策略信号1"):
        """计算策略信号 - 可以扩展多个不同的策略"""
        last_index = len(data) - 1
        if last_index < 0:
            return None

        # 获取5分钟周期数据
        symbol = 'BTCUSDT'
        five_min_data = self.get_5min_data(symbol)

        ma5 = self.calculate_ma(data, 5)
        ma10 = self.calculate_ma(data, 10)
        ma20 = self.calculate_ma(data, 20)
        rsi = self.calculate_rsi(data, 14)
        macd = self.calculate_macd(data)
        kdj = self.calculate_kdj(data)

        # 计算Fisher转换
        fisher_trend = 'neutral'
        if len(five_min_data) >= 9:
            fisher = self.calculate_fisher(five_min_data)
            fisher_last_index = len(fisher) - 1
            if fisher_last_index >= 0 and fisher[fisher_last_index] is not None:
                if fisher_last_index > 0 and fisher[fisher_last_index-1] is not None:
                    if fisher[fisher_last_index] > fisher[fisher_last_index-1]:
                        fisher_trend = 'up'
                    elif fisher[fisher_last_index] < fisher[fisher_last_index-1]:
                        fisher_trend = 'down'

        ma5_trend = self.get_trend(ma5, last_index)
        ma10_trend = self.get_trend(ma10, last_index)
        ma20_trend = self.get_trend(ma20, last_index)
        rsi_trend = self.get_trend(rsi, last_index)
        macd_trend = self.get_macd_trend(macd, last_index)
        kdj_cross = self.get_kdj_cross(kdj, last_index)

        volumes = [d['volume'] for d in data]
        volume_ma20_data = [{'close': d['volume']} for d in data]
        volume_ma20 = self.calculate_ma(volume_ma20_data, 20)[last_index]
        volume_trend = self.get_trend(volumes, last_index)

        # 根据策略名称生成不同的信号逻辑
        if strategy_name == "策略信号1":
            # 策略1：基于MACD和RSI的趋势跟踪
            signal_direction = 'neutral'
            confidence = 0.5
            
            if macd_trend in ['crossUp', 'strongUp'] and rsi[last_index] < 70:
                signal_direction = 'up'
                confidence = 0.7
            elif macd_trend in ['crossDown', 'strongDown'] and rsi[last_index] > 30:
                signal_direction = 'down'
                confidence = 0.7
                
        elif strategy_name == "策略信号2":
            # 策略2：基于KDJ和Fisher的反转策略
            signal_direction = 'neutral'
            confidence = 0.5
            
            if kdj_cross == 'goldenCross' and fisher_trend == 'up':
                signal_direction = 'up'
                confidence = 0.65
            elif kdj_cross == 'deathCross' and fisher_trend == 'down':
                signal_direction = 'down'
                confidence = 0.65
                
        elif strategy_name == "策略信号3":
            # 策略3：基于均线排列的策略
            signal_direction = 'neutral'
            confidence = 0.5
            
            if (ma5_trend == 'up' and ma10_trend == 'up' and ma20_trend == 'up' and 
                ma5[last_index] > ma10[last_index] > ma20[last_index]):
                signal_direction = 'up'
                confidence = 0.75
            elif (ma5_trend == 'down' and ma10_trend == 'down' and ma20_trend == 'down' and 
                  ma5[last_index] < ma10[last_index] < ma20[last_index]):
                signal_direction = 'down'
                confidence = 0.75
                
        elif strategy_name == "策略信号4":
            # 策略4：基于5分钟TD序列的策略（最高权重）
            signal_direction = 'neutral'
            confidence = 0.5
            
            # 获取5分钟数据计算TD序列
            symbol = 'BTCUSDT'
            five_min_data = self.get_5min_data(symbol)
            
            # 创建TD序列指标字典
            td_sequence_indicators = {
                'buy_setup': None,
                'sell_setup': None,
                'buy_countdown': None,
                'sell_countdown': None
            }
            
            if len(five_min_data) >= 9:
                td_sequence = self.calculate_td_sequence(five_min_data)
                td_last_index = len(five_min_data) - 1
                
                buy_countdown = td_sequence['buy_countdown'][td_last_index]
                sell_countdown = td_sequence['sell_countdown'][td_last_index]
                buy_setup = td_sequence['buy_setup'][td_last_index]
                sell_setup = td_sequence['sell_setup'][td_last_index]
                
                # TD序列信号判断逻辑
                if buy_countdown is not None and buy_countdown >= 9:
                    # TD买入倒计时完成，强烈看涨信号
                    signal_direction = 'up'
                    confidence = 0.95  # 最高置信度
                elif sell_countdown is not None and sell_countdown >= 9:
                    # TD卖出倒计时完成，强烈看跌信号
                    signal_direction = 'down'
                    confidence = 0.95  # 最高置信度
                elif buy_setup == 9:
                    # TD买入设置完成，看涨信号
                    signal_direction = 'up'
                    confidence = 0.85
                elif sell_setup == 9:
                    # TD卖出设置完成，看跌信号
                    signal_direction = 'down'
                    confidence = 0.85
                elif buy_countdown is not None and buy_countdown >= 7:
                    # TD买入倒计时接近完成，看涨信号
                    signal_direction = 'up'
                    confidence = 0.75
                elif sell_countdown is not None and sell_countdown >= 7:
                    # TD卖出倒计时接近完成，看跌信号
                    signal_direction = 'down'
                    confidence = 0.75
                    
                # 更新TD序列指标信息
                td_sequence_indicators = {
                    'buy_setup': buy_setup,
                    'sell_setup': sell_setup,
                    'buy_countdown': buy_countdown,
                    'sell_countdown': sell_countdown
                }
        else:
            # 默认策略
            signal_direction = 'neutral'
            confidence = 0.5

        # 创建基础indicators字典
        indicators = {
            'ma5': ma5[last_index],
            'ma10': ma10[last_index],
            'ma20': ma20[last_index],
            'rsi': rsi[last_index],
            'macd': macd,
            'kdj': kdj,
            'fisher_trend': fisher_trend,
            'macd_trend': macd_trend,
            'kdj_cross': kdj_cross,
            'volume': {
                'current': volumes[last_index],
                'ma20': volume_ma20,
                'trend': volume_trend
            }
        }
        
        # 如果是策略信号4，添加TD序列指标
        if strategy_name == "策略信号4":
            indicators['td_sequence'] = td_sequence_indicators
        
        return {
            'strategy_name': strategy_name,
            'direction': signal_direction,
            'confidence': confidence,
            'indicators': indicators
        }
    
    def combine_strategy_signals(self, signals_list):
        """组合多个策略信号，策略信号4具有最高权重"""
        if not signals_list:
            return {
                'direction': 'neutral',
                'confidence': 0.5,
                'type': 'combined'
            }
        
        # 计算加权平均方向和置信度
        up_score = 0
        down_score = 0
        total_weight = 0
        
        for signal in signals_list:
            # 策略信号4具有最高权重（权重为3.0），其他策略权重为1.0
            if signal['strategy_name'] == "策略信号4":
                weight = 3.0  # 最高权重
            else:
                weight = 1.0  # 普通权重
            
            if signal['direction'] == 'up':
                up_score += signal['confidence'] * weight
            elif signal['direction'] == 'down':
                down_score += signal['confidence'] * weight
            total_weight += weight
        
        # 确定最终方向
        if up_score > down_score:
            final_direction = 'up'
            final_confidence = min(0.95, up_score / total_weight)
        elif down_score > up_score:
            final_direction = 'down'
            final_confidence = min(0.95, down_score / total_weight)
        else:
            final_direction = 'neutral'
            final_confidence = 0.5
        
        return {
            'direction': final_direction,
            'confidence': final_confidence,
            'type': 'combined',
            'strategy_count': len(signals_list)
        }
    
    _5min_data_cache = {}
    _last_cache_time = 0
    
    def get_5min_data(self, symbol):
        current_time = datetime.now().minute
        if current_time % 5 == 0 and current_time != self._last_cache_time:
            data = self.fetch_historical_data(symbol, '5m')
            if data:
                if symbol not in self.historical_data:
                    self.historical_data[symbol] = {}
                self.historical_data[symbol]['5m'] = data
                self._5min_data_cache[symbol] = data
                self._last_cache_time = current_time
        return self._5min_data_cache.get(symbol, [])
    
    def get_rsi_level_description(self, rsi_value):
        if rsi_value is None:
            return 'N/A'
        if rsi_value > 80:
            return '极端超买'
        if rsi_value > 70:
            return '超买'
        if rsi_value < 20:
            return '极端超卖'
        if rsi_value < 30:
            return '超卖'
        return '中性'
    
    def get_macd_description(self, macd_trend):
        descriptions = {
            'strongUp': 'MACD指标呈强劲上升趋势',
            'crossUp': 'MACD指标形成金叉',
            'strongDown': 'MACD指标呈强劲下降趋势',
            'crossDown': 'MACD指标形成死叉',
            'neutral': 'MACD指标呈中性'
        }
        return descriptions.get(macd_trend, 'MACD指标无明显趋势')
    
    def get_operation_suggestion(self, prediction):
        if prediction['direction'] == 'up':
            return '买入' 
        elif prediction['direction'] == 'down':
            return '卖出' 
        return '观望'
    
    def get_trend_arrow(self, direction):
        arrows = {'up': '↗', 'down': '↘', 'neutral': '→'}
        return arrows.get(direction, '→')
    
    def format_timestamp(self, timestamp):
        if timestamp is None:
            return "N/A"
        try:
            dt = datetime.fromtimestamp(timestamp)
            return dt.strftime("%Y-%m-%d %H:%M:%S")
        except:
            return str(timestamp)
    
    def analyze_current_data(self, symbol, interval):
        data = self.historical_data.get(symbol, {}).get(interval)
        if not data or len(data) < 100:
            return None
        
        # 计算多个策略信号
        strategy_names = ["策略信号1", "策略信号2", "策略信号3", "策略信号4"]
        all_signals = []
        
        for strategy_name in strategy_names:
            signal = self.calculate_strategy_signals(data, strategy_name)
            if signal:
                all_signals.append(signal)
        
        # 组合策略信号
        combined_signal = self.combine_strategy_signals(all_signals)
        
        # 添加市场状态分析
        market_state = self.market_state_analyzer.analyze_market_state(data)
        
        result = {
            'combined_signal': combined_signal,
            'strategy_signals': all_signals,
            'market_state': market_state
        }
        
        self.strategy_signals[symbol][interval] = result
        return result
    
    async def start_analysis(self, interval):
        await self.fetch_data_for_all_symbols(interval)
        
        results = []
        for symbol in self.symbols:
            signals_data = self.analyze_current_data(symbol, interval)
            if not signals_data:
                continue
            
            # 进行回测
            backtest_result = await self.backtester.backtest_strategy(symbol, interval)
            win_rate = backtest_result['winRate'] if backtest_result else 0
            total_tests = backtest_result['totalTests'] if backtest_result else 0
            
            combined_signal = signals_data['combined_signal']
            strategy_signals = signals_data['strategy_signals']
            
            # 获取第一个策略的指标信息用于显示
            first_strategy = strategy_signals[0] if strategy_signals else {}
            indicators = first_strategy.get('indicators', {})
            rsi = indicators.get('rsi', 50)
            current_price = indicators.get('ma5', 0)
            
            # 构建卡片文本
            current_time = self.format_timestamp(int(datetime.now().timestamp()))
            is_reverse_human = win_rate < 50
            trend_direction = combined_signal['direction']
            trend_text = '看涨' if trend_direction == 'up' else '看跌' if trend_direction == 'down' else '横盘'
            
            if is_reverse_human:
                if trend_direction == 'up':
                    trend_direction = 'down'
                    trend_text = '看跌'
                elif trend_direction == 'down':
                    trend_direction = 'up'
                    trend_text = '看涨'
                trend_text = '逆反人性' + trend_text
            
            # 计算逆反胜率
            reverse_win_rate = None
            if is_reverse_human and backtest_result and 'signals' in backtest_result:
                correct_predictions = backtest_result.get('correctPredictions', 0)
                total_tests = backtest_result.get('totalTests', 0)
                reverse_correct = total_tests - correct_predictions
                reverse_win_rate = round((reverse_correct / total_tests) * 100) if total_tests > 0 else 0
            
            card_text = [
                f"{symbol} 行情分析",
                f"{interval} | {current_time}",
                "趋势判断",
                f"{self.get_trend_arrow(trend_direction)} {trend_text} ({int(combined_signal['confidence'] * 100)}%)",
                "回测胜率",
                f"{win_rate}%",
                f"赢{backtest_result.get('correctPredictions', 0) if backtest_result else 0}次/共{total_tests}次"
            ]
            
            # 如果是逆反人性判断，添加逆反胜率信息
            if is_reverse_human and reverse_win_rate is not None:
                card_text.extend([
                    "逆反胜率",
                    f"{reverse_win_rate}%",
                    f"赢{backtest_result.get('totalTests', 0) - backtest_result.get('correctPredictions', 0)}次/共{backtest_result.get('totalTests', 0)}次"
                ])
            
            # 添加策略信号信息
            card_text.extend(["\n=== 策略信号详情 ==="])
            for i, signal in enumerate(strategy_signals):
                signal_direction = '看涨' if signal['direction'] == 'up' else '看跌' if signal['direction'] == 'down' else '观望'
                card_text.append(f"{signal['strategy_name']}: {signal_direction} ({int(signal['confidence'] * 100)}%)")
            
            # 添加市场状态信息
            market_state = signals_data.get('market_state', {})
            if market_state:
                high_low_structure_map = {
                    'uptrend': '上涨趋势',
                    'downtrend': '下跌趋势',
                    'potential_uptrend': '潜在上涨',
                    'potential_downtrend': '潜在下跌',
                    'ranging': '区间震荡',
                    'neutral': '中性'
                }
                ma_alignment_map = {
                    'bullish': '多头排列',
                    'bearish': '空头排列',
                    'neutral': '中性排列'
                }
                
                high_low_structure = market_state.get('details', {}).get('high_low_structure', 'N/A')
                ma_alignment = market_state.get('details', {}).get('ma_alignment', 'N/A')
                
                card_text.extend([
                    "\n=== 市场状态 ===",
                    f"状态描述: {market_state.get('description', 'N/A')}",
                    f"ADX: {market_state.get('details', {}).get('adx', 'N/A')}",
                    f"ATR: {market_state.get('details', {}).get('atr', 'N/A')}",
                    f"波动率: {market_state.get('details', {}).get('volatility', 'N/A')}",
                    f"高低点结构: {high_low_structure_map.get(high_low_structure, high_low_structure)}",
                    f"均线排列: {ma_alignment_map.get(ma_alignment, ma_alignment)}"
                ])
            
            card_text.extend([
                "\n=== 技术指标 ===",
                f"RSI: {rsi:.2f} ({self.get_rsi_level_description(rsi)})",
                f"当前价格: ${current_price:.2f}",
                f"策略数量: {len(strategy_signals)}个"
            ])
            
            results.append("\n".join(card_text))
        
        return results


class Backtester:
    def __init__(self):
        self.historical_data = {}
        self.backtest_results = {}
    
    async def backtest_strategy(self, symbol, current_interval):
        analyzer = CryptoAnalyzer()
        await analyzer.fetch_data_for_all_symbols('1m')
        print("正在回测" + current_interval)
        
        historical_data = analyzer.historical_data.get(symbol, {}).get('1m')
        if not historical_data or len(historical_data) < 100:
            return None
        
        return self.run_backtest(historical_data, analyzer)
    
    def run_backtest(self, data, analyzer, test_periods=200):
        max_periods = min(test_periods, len(data) - 100)
        signals = []
        correct_predictions = 0
        total_predictions = 0
        
        for i in range(100, len(data) - 10):
            if total_predictions >= max_periods:
                break
                
            test_data = data[:i+1]
            # 使用组合策略信号进行回测
            strategy_names = ["策略信号1", "策略信号2", "策略信号3", "策略信号4"]
            all_signals = []
            
            for strategy_name in strategy_names:
                signal = analyzer.calculate_strategy_signals(test_data, strategy_name)
                if signal:
                    all_signals.append(signal)
            
            combined_signal = analyzer.combine_strategy_signals(all_signals)
            
            if combined_signal:
                total_predictions += 1
                current_price = data[i]['close']
                future_price = data[i + 10]['close']
                actual_movement = 'up' if future_price > current_price else 'down'
                
                if combined_signal['direction'] == actual_movement:
                    correct_predictions += 1
                
                signals.append({
                    'time': data[i]['time'],
                    'prediction': combined_signal['direction'],
                    'actual': actual_movement,
                    'correct': combined_signal['direction'] == actual_movement
                })
        
        win_rate = round((correct_predictions / total_predictions) * 100) if total_predictions > 0 else 0
        
        return {
            'winRate': win_rate,
            'totalTests': total_predictions,
            'correctPredictions': correct_predictions,
            'signals': signals
        }